package com.xcity.game.skill;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.xcity.db.entity.Player;
import com.xcity.game.common.Cause;
import com.xcity.game.common.MessageConst;
import com.xcity.game.skill.PlayerSkill.SkillPhase;
import com.xcity.game.skill.state.Phase;
import com.xcity.game.skill.state.State;
import com.xcity.game.skill.template.SkillTemplate;

import naga.x.App;
import naga.x.common.Updatable;
import naga.x.game.template.TemplateService;
import naga.x.game.time.TimeUpdater;

@Deprecated
public class SkillManager implements Updatable {

	private Player owner;
	private List<PlayerSkill> skills;
	private PlayerSkill activatedSkill; // 当前激活了的技能
	
	protected static final Logger LOG = PlayerSkill.LOG;
	
	public SkillManager(Player player, List<PlayerSkill> skills) {
		this.owner = player;
		if (skills == null) {
			skills = new ArrayList<PlayerSkill>(7);
		}
		for (int i = skills.size() - 1; i >= 0; i--) {
			PlayerSkill skill = skills.get(i);
			skill.vm = this;
			if (skill.getState() == State.ACTIVATED) {
				activatedSkill = skill;
			}
		}
		this.skills = skills;
	}
	
	public Player getOwner() {
		return owner;
	}
	
	public void setOwner(Player owner) {
		this.owner = owner;
	}

	public List<PlayerSkill> getSkills() {
		return skills;
	}
	
	public PlayerSkill getActivatedSkill() {
		return activatedSkill;
	}
	
	public PlayerSkill getSkill(int id) {
		if (activatedSkill != null && activatedSkill.getId() == id) {
			return activatedSkill;
		}
		for (int i = skills.size() - 1; i >= 0; i--) {
			PlayerSkill skill = skills.get(i);
			if (skill.getId() == id) {
				return skill;
			}
		}
		return null;
	}
	
	public PlayerSkill addSkill(int id, String cause) throws SkillException {
		SkillTemplate template = App.getApp().getServiceManager().get(TemplateService.class).get(SkillTemplate.class, id);
		if (template == null) {
			throw new SkillException(MessageConst.SKILL_NOT_FOUND);
		}
		return addSkill(template, cause);
	}
	
	public PlayerSkill addSkill(SkillTemplate template, String cause) throws SkillException {
		if (getSkill(template.getId()) != null) {
			throw new SkillException(MessageFormat.format(MessageConst.SKILL_EXISTS, template.getName()));
		}
		PlayerSkill skill = new PlayerSkill(this, template);
		int index = -1;
		for (int i = 0; i < skills.size(); i++) {
			PlayerSkill s = skills.get(i);
			if (s.getId() > skill.getId()) {
				index = i;
				break;
			}
		}
		if (index >= 0) {
			skills.add(index, skill);
		} else {
			skills.add(skill);
		}
		LOG.info("[ADDSKILL]ID[{}]SKILL[{}]CAUSE[{}]", owner.getId(), skill.getId(), cause);
		return skill;
	}
	
	public PlayerSkill addSkillWithoutException(SkillTemplate template, String cause) {
		PlayerSkill ps = new PlayerSkill(this, template);
		skills.add(ps);
		if (ps.getState() == State.ACTIVATED) {
			PlayerSkill pre = activatedSkill;
			if (pre != null) {
				pre.setState(State.UNACTIVATED);
			}
			activatedSkill = ps;
		}
		LOG.info("[ADDSKILL]ID[{}]SKILL[{}]CAUSE[{}]", owner.getId(), ps.getId(), cause);
		return ps;
	}
	
	public PlayerSkill activate(int id) throws SkillException {
		PlayerSkill skill = activatedSkill;
		if (skill != null && skill.getId() == id) {
			throw new SkillException(MessageConst.SKILL_ACTIVATED);
		}
		skill = getSkill(id);
		if (skill == null) {
			throw new SkillException(MessageConst.SKILL_NOT_FOUND);
		}
		skill.changeState(State.ACTIVATED);
		if (activatedSkill != null) {
			activatedSkill.changeState(State.UNACTIVATED);
		}
		activatedSkill = skill;
		return skill;
	}
	
	public PlayerSkill unactivate() throws SkillException {
		PlayerSkill skill = activatedSkill;
		if (skill == null) {
			throw new SkillException(MessageConst.SKILL_UNACTIVATED);
		}
		skill.changeState(State.UNACTIVATED);
		activatedSkill = null;
		return skill;
	}
	
	static final SerializeFilter SERIALIZE_FILTER = new PropertyPreFilter() {
		@Override
		public boolean apply(JSONSerializer serializer, Object object, String name) {
			return !"name".equals(name)
					&& !"desc".equals(name)
					&& !"icon".equals(name)
					&& !"maxExp".equals(name)
					&& !"maxLevel".equals(name)
					&& !"exp0".equals(name)
					&& !"expOffset".equals(name);
		}
	};
	public String toString() {
		return JSON.toJSONString(skills, SERIALIZE_FILTER);
	}

	@Override
	public boolean update() {
		for (int i = 0, size = skills.size(); i < size; i++) {
			skills.get(i).update();
		}
		return true;
	}

	protected void playerLogin() {
		for (int i = skills.size() - 1; i >= 0; i--) {
			PlayerSkill skill = skills.get(i);
			SkillPhase phase = skill.getPhase();
			if (phase.state == Phase.STATE_RUNNING) {
				long time;
				if (phase.id == Phase.LEARN || owner.getLastLogoutTime() == null) {
					// 学习阶段不累计离线时间
					time = TimeUpdater.getInstance().now();
				} else {
					time = owner.getLastLogoutTime().getTime();
				}
				skill.startPhaseLearn0(time, Cause.LOGIN);
			}
		}
	}
	
	protected void playerLogout() {
		for (int i = skills.size() - 1; i >= 0; i--) {
			PlayerSkill skill = skills.get(i);
			skill.update(true, Cause.LOGOUT);
		}
	}
	
}
